package com.bbva.itradecomex.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.event.ComponentSystemEvent;

import org.apache.log4j.Logger;
import org.primefaces.event.DateSelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.jsf.FacesContextUtils;

import com.bbva.itradecomex.bo.iface.ConsultaComunBO;
import com.bbva.itradecomex.bo.iface.FinanciamientoBO;
import com.bbva.itradecomex.domain.ArbolClaseFia;
import com.bbva.itradecomex.domain.FinanciamientoDetalle;
import com.bbva.itradecomex.domain.FinanciamientoResumen;
import com.bbva.itradecomex.form.FinanciamientoForm;
import com.bbva.itradecomex.util.Constantes;
import com.bbva.itradecomex.util.ITradexUtil;
import com.bbva.itradecomex.util.MessageProvider;
import com.thoughtworks.xstream.XStream;

@Controller
@RequestScoped
@ManagedBean
public class FinanciamientoController {

	private static final Logger log = Logger.getLogger(FinanciamientoController.class);
	
	private static final XStream XSTREAM = new XStream();

	@Autowired
	private FinanciamientoBO financiamientoBO;
	@Autowired
	private ConsultaComunBO consultaComunBO;

	private FinanciamientoForm financiamientoForm;

	private List<FinanciamientoDetalle> listFinanciamientoDetalle;

	private TreeNode rootImp;
	private TreeNode rootExp;

	private FinanciamientoResumen footerImp;
	private FinanciamientoResumen footerExp;
	private FinanciamientoResumen footerTotalImpExp;
	
	private TreeNode[] selectedNodeClaseFiaImpo;
	private TreeNode arbolClaseFiaImpo;
	private TreeNode[] selectedNodeClaseFiaExpo;
	private TreeNode arbolClaseFiaExpo;
	
	private boolean buscar;

	public void onPageLoad(ComponentSystemEvent event) {
		try {
			if (!FacesContext.getCurrentInstance().isPostback()) {
				inicializarValores();
				buscar = true;
				financiamientoForm = new FinanciamientoForm();
				Calendar cal = Calendar.getInstance();
				cal.set(Calendar.YEAR, cal.get(Calendar.YEAR));
				cal.set(Calendar.MONTH, 0);
				cal.set(Calendar.DAY_OF_MONTH, 1);
				financiamientoForm.setInFechaDesde(cal.getTime());
				financiamientoForm.setInFechaHasta(Calendar.getInstance().getTime());

				FacesContext context = FacesContext.getCurrentInstance();
				ComunController comunController = (ComunController) FacesContextUtils
						.getWebApplicationContext(context).getBean("comunController");
				comunController.inicializarValores();
				comunController.cargarListTipoDocumento();
				comunController.cargarTipoOperacion();
				comunController.cargarSituacion();
				
				inicializarArbolClasesCheck();
				cargarArbolClaseFiaImpCheck();
				cargarArbolClaseFiaExpCheck();
				
				buscarFinanciamientoAction();
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage(),e);
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
					MessageProvider.getInstance().getValue("MSG_ERROR_TITLE_GENERAL"),
					MessageProvider.getInstance().getValue("MSG_ERROR_DESCRIP_GENERAL")));
		}
	}
	
	public void cargarArbolClaseFiaImpCheck() throws Exception{
		List<ArbolClaseFia> listArbolFiaImpo = consultaComunBO.getConsListArbolClaseFiaImpo(Constantes.TIPO_IMPORTACION);		
		arbolClaseFiaImpo = crearArbolClasesCheck(listArbolFiaImpo);
		ITradexUtil.configInitialTreeNode(arbolClaseFiaImpo, true);
	}
	
	public void cargarArbolClaseFiaExpCheck() throws Exception{
		List<ArbolClaseFia> listArbolFiaExpo = consultaComunBO.getConsListArbolClaseFiaExpo(Constantes.TIPO_EXPORTACION);		
		arbolClaseFiaExpo = crearArbolClasesCheck(listArbolFiaExpo);
		ITradexUtil.configInitialTreeNode(arbolClaseFiaExpo, true);
	}
	
	public void updateArbolClasesCheck(){
		try{
			inicializarArbolClasesCheck();
			String codTipoOperacion = Constantes.VACIO;
		   
			FacesContext context = FacesContext.getCurrentInstance();
				ComunController comunController = (ComunController) FacesContextUtils
					.getWebApplicationContext(context).getBean("comunController");
		   
			if(comunController.getTipoOperacionSeleccionado() != null && 
				   comunController.getTipoOperacionSeleccionado().getValor1() != null){
				codTipoOperacion = comunController.getTipoOperacionSeleccionado().getValor1();
			}
			
			if(Constantes.VACIO.equals(codTipoOperacion)){
				cargarArbolClaseFiaImpCheck();
				cargarArbolClaseFiaExpCheck();
			}else if(Constantes.TIPO_IMPORTACION.equals(codTipoOperacion)){
				cargarArbolClaseFiaImpCheck();
			}else if(Constantes.TIPO_EXPORTACION.equals(codTipoOperacion)){
				cargarArbolClaseFiaExpCheck();
			}
		}catch(Exception e){
			e.printStackTrace();
			log.error(e.getMessage(), e);
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
					MessageProvider.getInstance().getValue("MSG_ERROR_TITLE_GENERAL"),
					MessageProvider.getInstance().getValue("MSG_ERROR_DESCRIP_GENERAL")));
		}
	}
   
	private TreeNode crearArbolClasesCheck(List<ArbolClaseFia> list)  throws Exception{
		
		TreeNode root = null;
		
		if(list != null){
			root = new DefaultTreeNode(Constantes.TREE_ROOT, null);
			if(list.size() > 0){
                
				TreeNode treeNode;
                
		        for (int i = 0; i < list.size(); i++) {
		        	ArbolClaseFia arbolFia = list.get(i);
		            
		            if (arbolFia.getIdNodoPadre() == null) {
		            	
		            	ArbolClaseFia arbolFiaNode = new ArbolClaseFia();
		            	arbolFiaNode.setIdNodo(arbolFia.getIdNodo());
		            	arbolFiaNode.setIdNodoPadre(arbolFia.getIdNodoPadre());
		            	arbolFiaNode.setDescripcion(arbolFia.getDescripcion());
		            	arbolFiaNode.setDetalle(arbolFia.getDetalle());
		            	
		                treeNode = new DefaultTreeNode(arbolFiaNode, root);
		                
		                adicionarHijosClases(arbolFia, treeNode, list);
		            } else {
		            	break;
		            }
		        }
			}
		}
		
        return root;
    }
	
    private void adicionarHijosClases(ArbolClaseFia arbolFia, TreeNode treeNode, List<ArbolClaseFia> list)
   		 throws Exception{
    	for (int i = 0; i < list.size(); i++) {
    		ArbolClaseFia drArbolFia = list.get(i);

    		if (arbolFia.getIdNodo().equals(drArbolFia.getIdNodoPadre())){
           	
    			ArbolClaseFia arbolFiaNode = new ArbolClaseFia();
	           	arbolFiaNode.setIdNodo(drArbolFia.getIdNodo());
	           	arbolFiaNode.setIdNodoPadre(drArbolFia.getIdNodoPadre());
	           	arbolFiaNode.setDescripcion(drArbolFia.getDescripcion());
	           	arbolFiaNode.setDetalle(drArbolFia.getDetalle());

	           	TreeNode drTreeNode = new DefaultTreeNode(arbolFiaNode, treeNode);
	           	adicionarHijosClases(drArbolFia, drTreeNode, list);
           	}
    	}
    }

	public void validateDateChange(AjaxBehaviorEvent event) {
		if (ITradexUtil.esFecha1MayorFecha2(
				financiamientoForm.getInFechaDesde(),
				financiamientoForm.getInFechaHasta())) {
			buscar = false;
			FacesContext.getCurrentInstance().addMessage(null,new FacesMessage(FacesMessage.SEVERITY_ERROR,
					MessageProvider.getInstance().getValue("MSG_ERROR_TITLE_VALIDA_FECHA"),
					MessageProvider.getInstance().getValue("MSG_ERROR_DESCRIP_VALIDA_FECHA")));
		}else{
			buscar = true;
		}
	}

	public void validateDateDateSelect(DateSelectEvent event) {
		if (ITradexUtil.esFecha1MayorFecha2(
				financiamientoForm.getInFechaDesde(),
				financiamientoForm.getInFechaHasta())) {
			buscar = false;
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
					MessageProvider.getInstance().getValue("MSG_ERROR_TITLE_VALIDA_FECHA"),
					MessageProvider.getInstance().getValue("MSG_ERROR_DESCRIP_VALIDA_FECHA")));
		}else{
			buscar = true;
		}
	}
	
	public void validateRangoMonto(AjaxBehaviorEvent event){
		BigDecimal bg1 = financiamientoForm.getInMontoDesde();
		BigDecimal bg2 = financiamientoForm.getInMontoHasta();

		if(Constantes.VALOR_CERO.equals(String.valueOf(bg1)) || Constantes.VALOR_CERO.equals(String.valueOf(bg2))){
			if(Constantes.VALOR_CERO.equals(String.valueOf(bg1))){
				financiamientoForm.setInMontoDesde(null);
			}else{
				financiamientoForm.setInMontoHasta(null);
			}	
		}else if(bg1 != null && bg2 != null){
			if(bg1.compareTo(bg2) == 1){
				buscar = false;
				FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
						MessageProvider.getInstance().getValue("MSG_ERROR_TITLE_VALIDA_MONTO"),
						MessageProvider.getInstance().getValue("MSG_ERROR_DESCRIP_VALIDA_MONTO")));
			}else{
				buscar = true;
			}
		}
	}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
	public void buscarFinanciamientoAction() {
		if(buscar){
			try {
				inicializarValores();
				FacesContext context = FacesContext.getCurrentInstance();
				ComunController comunController = (ComunController) FacesContextUtils
						.getWebApplicationContext(context).getBean("comunController");
				String codPais = "";
				String descPais = "";
				String codMoneda = "";
				String descMoneda = "";
				String codTipoDocumento = "";
				String descTipoDocumento = "";
				String codTipoOperacion = "";
				String descTipoOperacion = "";
				String codSituacion = "";
				String descSituacion = "";
				String arrayArbolClaseImpo = "";
				String arrayArbolClaseExpo = "";
	
				if (comunController.getPaisSeleccionado() != null) {
					if (comunController.getPaisSeleccionado().getCodPais() != null) {
						codPais = comunController.getPaisSeleccionado().getCodPais();
					}
					if (comunController.getPaisSeleccionado().getDescripcion() != null) {
						descPais = comunController.getPaisSeleccionado().getDescripcion();
					}
				}
	
				if (comunController.getMonedaSeleccionado() != null) {
					if (comunController.getMonedaSeleccionado().getCodMoneda() != null) {
						codMoneda = comunController.getMonedaSeleccionado().getCodMoneda();
					}
					if (comunController.getMonedaSeleccionado().getDescripcion() != null) {
						descMoneda = comunController.getMonedaSeleccionado().getDescripcion();
					}
				}
	
				if (comunController.getTipoDocSeleccionado() != null) {
					if (comunController.getTipoOperacionSeleccionado().getValor1() != null) {
						codTipoDocumento = comunController.getTipoOperacionSeleccionado().getValor1();
					}
					if (comunController.getTipoOperacionSeleccionado().getDescripcion() != null) {
						descTipoDocumento = comunController.getTipoOperacionSeleccionado().getDescripcion();
					}
				}
	
				if (comunController.getTipoOperacionSeleccionado() != null) {
					if (comunController.getTipoOperacionSeleccionado().getValor1() != null) {
						codTipoOperacion = comunController.getTipoOperacionSeleccionado().getValor1();
					}
					if (comunController.getTipoOperacionSeleccionado().getDescripcion() != null) {
						descTipoOperacion = comunController.getTipoOperacionSeleccionado().getDescripcion();
					}
				}
	
				if (comunController.getSituacionSeleccionado() != null) {
					if (comunController.getSituacionSeleccionado().getValor1() != null) {
						codSituacion = comunController.getSituacionSeleccionado().getValor1();
					}
					if (comunController.getSituacionSeleccionado().getDescripcion() != null) {
						descSituacion = comunController.getSituacionSeleccionado().getDescripcion();
					}
				}
	
				if (selectedNodeClaseFiaImpo != null && selectedNodeClaseFiaImpo.length > 0) {
					TreeNode[] arbolImpoSeleccionado = selectedNodeClaseFiaImpo;
					arrayArbolClaseImpo = getArrayCodigoClasesTree(Arrays.asList(arbolImpoSeleccionado));
				}
	
				if (selectedNodeClaseFiaExpo != null && selectedNodeClaseFiaExpo.length > 0) {
					TreeNode[] arbolExpoSeleccionado = selectedNodeClaseFiaExpo;
					arrayArbolClaseExpo = getArrayCodigoClasesTree(Arrays.asList(arbolExpoSeleccionado));
				}
	
				financiamientoForm.setInBuscarCliente(codTipoDocumento);
				financiamientoForm.setInCodPais(codPais);
				financiamientoForm.setInImpoExpo(codTipoOperacion);
				financiamientoForm.setInCodSituacion(codSituacion);
				financiamientoForm.setInCodMoneda(codMoneda);
				financiamientoForm.setInArrayClaseFiaImpo(arrayArbolClaseImpo);
				financiamientoForm.setInArrayClaseFiaExpo(arrayArbolClaseExpo);
	
				financiamientoForm.setDescInCodPais(descPais);
				financiamientoForm.setDescInCodMoneda(descMoneda);
				financiamientoForm.setDescInBuscarCliente(descTipoDocumento);
				financiamientoForm.setDescInImpoExpo(descTipoOperacion);
				financiamientoForm.setDescInCodSituacion(descSituacion);
	
				cargarResumenArbolImpExp(codTipoOperacion);

				listFinanciamientoDetalle = financiamientoBO.getListFinanciamientoDetalle(financiamientoForm);
				financiamientoBO.setTotalFinancResumenExpImp(footerTotalImpExp, footerImp, footerExp);
			} catch (Exception e) {
				e.printStackTrace();
				log.error(e.getMessage(),e);
				FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
						MessageProvider.getInstance().getValue("MSG_ERROR_TITLE_GENERAL"),
						MessageProvider.getInstance().getValue("MSG_ERROR_DESCRIP_GENERAL")));
			}			
		}else{
			log.error("Error en el formulario");
		}
	}
	
	private void cargarResumenArbolImpExp(String codTipoOperacion){
		try {
			if (Constantes.VACIO.equals(codTipoOperacion)) {
				cargarResumenArbolImp();
				cargarResumenArbolExp();
			} else if (Constantes.TIPO_IMPORTACION.equals(codTipoOperacion)) {
				cargarResumenArbolImp();
			} else if (Constantes.TIPO_EXPORTACION.equals(codTipoOperacion)) {
				cargarResumenArbolExp();
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage(),e);
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
					MessageProvider.getInstance().getValue("MSG_ERROR_TITLE_GENERAL"),
					MessageProvider.getInstance().getValue("MSG_ERROR_DESCRIP_GENERAL")));
		}	
	}
	
	private void cargarResumenArbolImp() throws Exception{
		List<FinanciamientoResumen> listFinancResumenImp = financiamientoBO
				.getListFinanciamientoResumenImp(financiamientoForm);
		rootImp = iniciarCrearTreeNode(listFinancResumenImp, 0);

		updateTreeNode(rootImp);
	}

	private void cargarResumenArbolExp() throws Exception{
		List<FinanciamientoResumen> listFinancResumenExp = financiamientoBO
				.getListFinanciamientoResumenExp(financiamientoForm);
		rootExp = iniciarCrearTreeNode(listFinancResumenExp, 1);

		updateTreeNode(rootExp);
	}


	private TreeNode iniciarCrearTreeNode(List<FinanciamientoResumen> listFinancResumen, int tipo)
			throws Exception {
		TreeNode rootTree = crearTreeNode(listFinancResumen);
		if (rootTree != null && rootTree.getChildCount() > 0) {
			ITradexUtil.configInitialTreeNode(rootTree, false);
			switch (tipo) {
			case 0: financiamientoBO.setFooterImpExp(listFinancResumen, footerImp);
					break;
			case 1: financiamientoBO.setFooterImpExp(listFinancResumen, footerExp);
					break;
			}
		}
		return rootTree;
	}

	private TreeNode crearTreeNode(List<FinanciamientoResumen> list)
			throws Exception {

		TreeNode root = null;

		if (list != null) {
			root = new DefaultTreeNode(Constantes.TREE_ROOT, null);
			if (list.size() > 0) {
				TreeNode treeNode;
				for (int i = 0; i < list.size(); i++) {
					FinanciamientoResumen financResumen = list.get(i);

					if (financResumen.getCodClasePadre() == null) {
						FinanciamientoResumen finanResumenNode = new FinanciamientoResumen(
								financResumen.getDescClase(),
								financResumen.getTotOper(),
								financResumen.getTotMonto());								

						treeNode = new DefaultTreeNode(finanResumenNode, root);

						adicionaHijos(financResumen, treeNode, list);
					} else {
						break;
					}
				}
			}
		}

		return root;
	}
	
	private void adicionaHijos(FinanciamientoResumen financResumen,
			TreeNode treeNode, List<FinanciamientoResumen> list)
			throws Exception {
		for (int i = 0; i < list.size(); i++) {
			FinanciamientoResumen drFinancResumen = list.get(i);
			
			if (financResumen.getCodClase().equals(drFinancResumen.getCodClasePadre())) {
				FinanciamientoResumen finanResumenNode = new FinanciamientoResumen(
						drFinancResumen.getDescClase(),
						drFinancResumen.getTotOper(),
						drFinancResumen.getTotMonto());
				
				TreeNode drTreeNode = new DefaultTreeNode(finanResumenNode,
						treeNode);
				adicionaHijos(drFinancResumen, drTreeNode, list);
			}
		}
	}
	
	private void updateTreeNode(TreeNode treeNode) {
		if (treeNode != null) {
			List<TreeNode> listTreeNode = treeNode.getChildren();

			for (int i = 0; i < listTreeNode.size(); i++) {
				TreeNode nodeHijo = listTreeNode.get(i);

				if(nodeHijo.getChildren().size() == 0){
					updateNode(nodeHijo);
					break;
				}

				updateTreeNode(nodeHijo);
			}
		}
	}
	
	private void updateNode(TreeNode nodeHijo) {
		if(nodeHijo.getParent() != null && !Constantes.TREE_ROOT.equals(nodeHijo.getParent().getData())){
			TreeNode nodePadre = nodeHijo.getParent();
			List<TreeNode> listTreeNode = nodePadre.getChildren();
			
			BigDecimal totOper = new BigDecimal(0);
			BigDecimal totMonto = new BigDecimal(0);
			
			for (int i = 0; i < listTreeNode.size(); i++) {
				TreeNode node = listTreeNode.get(i);
				FinanciamientoResumen finan = (FinanciamientoResumen)node.getData();
				totOper = ITradexUtil.addBigDecimal(totOper, finan.getTotOper());
				totMonto = ITradexUtil.addBigDecimal(totMonto, finan.getTotMonto());
			}
			
			((FinanciamientoResumen)nodePadre.getData()).setTotOper(totOper);
			((FinanciamientoResumen)nodePadre.getData()).setTotMonto(totMonto);

			updateNode(nodePadre);
		}
	}

	public void exportDocument(String tipoDoc){
		if ((rootImp != null && rootImp.getChildCount() > 0)
				|| (rootExp != null && rootExp.getChildCount() > 0)
				|| (listFinanciamientoDetalle != null && listFinanciamientoDetalle
						.size() > 0)) {
			
			List<ArbolClaseFia> listArbolClaseFiaImpSelected = new ArrayList<ArbolClaseFia>();
			if(arbolClaseFiaImpo != null && arbolClaseFiaImpo.getChildCount() > 0){
				List<TreeNode> listTreeNodeClaseImpo = null;
				if(selectedNodeClaseFiaImpo != null){
					listTreeNodeClaseImpo = new ArrayList<TreeNode>(Arrays.asList(selectedNodeClaseFiaImpo));
				}
				buildTreeNodeClasesCheckToListReport(arbolClaseFiaImpo, listArbolClaseFiaImpSelected, "", listTreeNodeClaseImpo);
			}
			
			List<ArbolClaseFia> listArbolClaseFiaExpSelected = new ArrayList<ArbolClaseFia>();
			if(arbolClaseFiaExpo != null && arbolClaseFiaExpo.getChildCount() > 0){
				List<TreeNode> listTreeNodeClaseExpo = null;
				if(selectedNodeClaseFiaExpo != null){
					listTreeNodeClaseExpo = new ArrayList<TreeNode>(Arrays.asList(selectedNodeClaseFiaExpo));
				}
				buildTreeNodeClasesCheckToListReport(arbolClaseFiaExpo, listArbolClaseFiaExpSelected, "", listTreeNodeClaseExpo);
			}
			
			List<FinanciamientoResumen> listFinanResumenImp = new ArrayList<FinanciamientoResumen>();
			buildTreeNodeResumenToListReport(rootImp, listFinanResumenImp, "");

			List<FinanciamientoResumen> listFinanResumenExp = new ArrayList<FinanciamientoResumen>();
			buildTreeNodeResumenToListReport(rootExp, listFinanResumenExp, "");

			Map<String, Object> parametros = new HashMap<String, Object>();
			parametros.put("listArbolClaseFiaImpSelected", listArbolClaseFiaImpSelected);
			parametros.put("listArbolClaseFiaExpSelected", listArbolClaseFiaExpSelected);
			parametros.put("listFinanResumenImp", listFinanResumenImp);
			parametros.put("listFinanResumenExp", listFinanResumenExp);
			parametros.put("listFinanciamientoDetalle", listFinanciamientoDetalle);
			parametros.put("obFooterImp", footerImp);
			parametros.put("obFooterExp", footerExp);
			parametros.put("obFooterImpExp", footerTotalImpExp);
			parametros.put("obForm", financiamientoForm);
			Date mydate = new Date();
			parametros.put("dateReport", mydate);
			
			String nombreFile = "FINANCIAMIENTOS_"+ITradexUtil.convertUtilDateToString(mydate, Constantes.FORMAT_DATE_MM_DD_yyyy);
			
			if(Constantes.ARCHIVO_EXCEL.equals(tipoDoc)){
				ITradexUtil.exportXLSJasperEmptyDS(parametros, "/xmlReport/Financiamiento/Financiamiento_excel.jasper", nombreFile);
			}else if(Constantes.ARCHIVO_PDF.equals(tipoDoc)){
				ITradexUtil.exportPDFEmptyDS(parametros, "/xmlReport/Financiamiento/Financiamiento.jasper", nombreFile);
			}
		}
	}

	private void buildTreeNodeResumenToListReport(TreeNode node,
			List<FinanciamientoResumen> listFinanResumen, String espacio) {
		if (node != null) {
			List<TreeNode> list = node.getChildren();
			boolean continuar = true;
			for (int i = 0; i < list.size(); i++) {
				TreeNode tnode = list.get(i);
				if (Constantes.TREE_ROOT.equals(node.getData())) {
					espacio = "  ";
				} else {
					if (i == 0) {
						espacio = espacio + "      ";
					}
				}
				
				if(tnode.getChildren().size() == 0){
					continuar = false;
				}

				FinanciamientoResumen finan = (FinanciamientoResumen)XSTREAM.fromXML(
							XSTREAM.toXML((FinanciamientoResumen) tnode.getData()));

				finan.setDescClase(espacio + finan.getDescClase());
				listFinanResumen.add(finan);
				
				if(continuar){
					buildTreeNodeResumenToListReport(tnode, listFinanResumen, espacio);
				}
			}
		}
	}
	
	private void buildTreeNodeClasesCheckToListReport(TreeNode node,
			List<ArbolClaseFia> listArbolClaseFia, String espacio, List<TreeNode> listCheckSeleccionado) {
		if (node != null) {
			List<TreeNode> list = node.getChildren();
			boolean continuar = true;
			for (int i = 0; i < list.size(); i++) {
				TreeNode tnode = list.get(i);
				if (Constantes.TREE_ROOT.equals(node.getData())) {
					espacio = "  ";
				} else {
					if (i == 0) {
						espacio = espacio + "      ";
					}
				}
				
				ArbolClaseFia arbolClaseFia = (ArbolClaseFia)XSTREAM.fromXML(
						XSTREAM.toXML((ArbolClaseFia) tnode.getData()));

				boolean flag = false;
				
				if(listCheckSeleccionado != null){
					for(int j=0; j<listCheckSeleccionado.size(); j++){
						TreeNode nodeSelected = listCheckSeleccionado.get(j);
						ArbolClaseFia arbol = (ArbolClaseFia)nodeSelected.getData();
						if(((arbol.getIdNodo()!=null && arbolClaseFia.getIdNodo()!=null) && 
								(arbol.getIdNodo().compareTo(arbolClaseFia.getIdNodo()) == 0)) ||
								(arbol.getIdNodo() == null && arbolClaseFia.getIdNodo() == null)){
							flag = true;
							listCheckSeleccionado.remove(j);
							break;
						}
					}
				}
				if(!flag){
					arbolClaseFia.setIsSelected(Boolean.FALSE);
					arbolClaseFia.setDescripcion(espacio + arbolClaseFia.getDescripcion());
				}else{
					arbolClaseFia.setIsSelected(Boolean.TRUE);
					arbolClaseFia.setDescripcion(espacio + arbolClaseFia.getDescripcion() + Constantes.CHECK);
				}
				listArbolClaseFia.add(arbolClaseFia);
				
				if(tnode.getChildren().size() == 0){
					continuar = false;
				}
				
				if(continuar){
					buildTreeNodeClasesCheckToListReport(tnode, listArbolClaseFia, espacio, listCheckSeleccionado);
				}
			}
		}
	}

	private String getArrayCodigoClasesTree(List<TreeNode> listTreeNode) {
		String arrayCodigo = null;
		if (listTreeNode != null && listTreeNode.size() > 0) {
			StringBuilder sb = new StringBuilder(Constantes.VACIO);
			for (TreeNode treeNode : listTreeNode) {
				ArbolClaseFia arbolFia = (ArbolClaseFia) treeNode.getData();
				if (arbolFia.getIdNodo() != null) {
					String idNodo = String.valueOf(arbolFia.getIdNodo());
					if (idNodo.length() > 0) {
						sb.append(Constantes.COMA);
						sb.append(idNodo);
					}
				}
			}
			arrayCodigo = sb.toString();
			if (arrayCodigo.length() > 1) {
				return arrayCodigo.substring(1, arrayCodigo.length());
			} else {
				return Constantes.VACIO;
			}
		}
		return arrayCodigo;
	}
    
	private void inicializarValores() {
		listFinanciamientoDetalle = null;
		rootImp = null;
		rootExp = null;
		footerImp = new FinanciamientoResumen();
		footerExp = new FinanciamientoResumen();
		footerTotalImpExp = new FinanciamientoResumen();
	}
	
	private void inicializarArbolClasesCheck(){
		selectedNodeClaseFiaImpo = null;
		arbolClaseFiaImpo = null;
		selectedNodeClaseFiaExpo = null;
		arbolClaseFiaExpo = null;
	}

	public List<FinanciamientoDetalle> getListFinanciamientoDetalle() {
		return listFinanciamientoDetalle;
	}

	public void setListFinanciamientoDetalle(
			List<FinanciamientoDetalle> listFinanciamientoDetalle) {
		this.listFinanciamientoDetalle = listFinanciamientoDetalle;
	}

	public TreeNode getRootImp() {
		return rootImp;
	}

	public void setRootImp(TreeNode rootImp) {
		this.rootImp = rootImp;
	}

	public TreeNode getRootExp() {
		return rootExp;
	}

	public void setRootExp(TreeNode rootExp) {
		this.rootExp = rootExp;
	}

	public FinanciamientoForm getFinanciamientoForm() {
		return financiamientoForm;
	}

	public void setFinanciamientoForm(FinanciamientoForm financiamientoForm) {
		this.financiamientoForm = financiamientoForm;
	}

	public FinanciamientoResumen getFooterImp() {
		return footerImp;
	}

	public void setFooterImp(FinanciamientoResumen footerImp) {
		this.footerImp = footerImp;
	}

	public FinanciamientoResumen getFooterExp() {
		return footerExp;
	}

	public void setFooterExp(FinanciamientoResumen footerExp) {
		this.footerExp = footerExp;
	}

	public FinanciamientoResumen getFooterImpExp() {
		return footerTotalImpExp;
	}

	public void setFooterImpExp(FinanciamientoResumen footerImpExp) {
		this.footerTotalImpExp = footerImpExp;
	}

	public TreeNode[] getSelectedNodeClaseFiaImpo() {
		return selectedNodeClaseFiaImpo;
	}

	public void setSelectedNodeClaseFiaImpo(TreeNode[] selectedNodeClaseFiaImpo) {
		this.selectedNodeClaseFiaImpo = selectedNodeClaseFiaImpo;
	}

	public TreeNode getArbolClaseFiaImpo() {
		return arbolClaseFiaImpo;
	}

	public void setArbolClaseFiaImpo(TreeNode arbolClaseFiaImpo) {
		this.arbolClaseFiaImpo = arbolClaseFiaImpo;
	}

	public TreeNode[] getSelectedNodeClaseFiaExpo() {
		return selectedNodeClaseFiaExpo;
	}

	public void setSelectedNodeClaseFiaExpo(TreeNode[] selectedNodeClaseFiaExpo) {
		this.selectedNodeClaseFiaExpo = selectedNodeClaseFiaExpo;
	}

	public TreeNode getArbolClaseFiaExpo() {
		return arbolClaseFiaExpo;
	}

	public void setArbolClaseFiaExpo(TreeNode arbolClaseFiaExpo) {
		this.arbolClaseFiaExpo = arbolClaseFiaExpo;
	}
}
